/************************************************************************

								Heroes IV
					  Copyright 2000, The 3DO Company

	------------------------------------------------------------------
  						       handler.h

	$Header: /game/handler.h $

	$NoKeywords: $

 ************************************************************************/

#ifndef HANDLER_H_INCLUDED
#define HANDLER_H_INCLUDED

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "abstract_function.h"
#include "counted_ptr.h"
// --------------------------------------------------------------------------
// generic callback functions.
//
// see also: function_handler.h, bound_handler.h, adaptor_handler.h
//
// typical usage:
//
// typedef t_handler_1<t_button*> t_button_handler;
//   - or -
// class t_button_handler : public t_handler_1<t_button*>
// {
// public:
//      t_button_handler( t_abstract_void_function_1<t_button*> function ) : t_handler_1(function)
//      {
//      }
// };
// 
// class t_button
// {
// public:
//     void set_handler( t_button_handler const& handler )
//     {
//         m_handler = handler;
//     }
//     void click()
//     {
//         m_handler( this );
//     }
// protected:
//     t_button_handler m_handler;
// };
//     
// void click_1( t_button* );
// 
// class t_client
// {
// public:
//     void click_2( t_button* );
// };
//
// void main()
// {
//     t_client client;
//     t_button button = new t_button;
//
//     button->set_handler( function_handler( click_1 ) );
//     button->click();
//     button->set_handler( bound_handler( client, &t_client::click_2 ) );
//     button->click();
// }
//
//

// no parameters
class t_handler_base : public t_counted_object, public t_abstract_function_0<void>
{
};

// one parameter
template <class type>
class t_handler_base_1 : public t_counted_object, public t_abstract_function_1<void, type>
{
};

// two parameters
template <class type_1, class type_2>
class t_handler_base_2 : public t_counted_object, public t_abstract_function_2<void, type_1, type_2>
{
};

// three parameters
template <class type_1, class type_2, class type_3>
class t_handler_base_3 : public t_counted_object, public t_abstract_function_3<void,type_1,type_2,type_3>
{
};

// ---------------------------------------------------------
// handler class which holds a virtual function and checks for null
// ---------------------------------------------------------
class t_handler
{
public:
	typedef t_handler_base t_function;

	t_handler() {};
	t_handler( t_function* function ) : m_function( function ) {}

	t_function*       get() const { return m_function; }
	operator t_function* () const { return m_function; }

	void operator()() const
	{
		if (m_function != 0)
			(*m_function)();
	}
protected:
	t_counted_ptr<t_function> m_function;
};


// ---------------------------------------------------------
// handler class which holds a virtual function and checks for null
// ---------------------------------------------------------
template < class type >
class t_handler_1
{
private:
	typedef type first_argument_type;
	typedef t_handler_base_1<type> t_function;

	t_counted_ptr<t_function> m_function;
public:
	t_handler_1() {}
	t_handler_1( t_function* function ) : m_function( function ) {}

	t_function*       get() const { return m_function; }
	operator t_function* () const { return m_function; }

	void operator()( type arg ) const
	{
		if (m_function != 0)
			(*m_function)( arg );
	}
};


// ---------------------------------------------------------
// handler class which holds a virtual function and checks for null
// ---------------------------------------------------------
template < class type_1, class type_2 >
class t_handler_2
{
public:
	typedef type_1 first_argument_type;
	typedef type_2 second_argument_type;
	typedef t_handler_base_2<type_1, type_2> t_function;

	t_handler_2() {}
	t_handler_2( t_function* function ) : m_function( function ) {}

	t_function*       get() const { return m_function; }
	operator t_function* () const { return m_function; }

	void operator()( type_1 arg_1, type_2 arg_2 ) const
	{
		if (m_function != 0)
			(*m_function)( arg_1, arg_2 );
	}
protected:
	t_counted_ptr<t_function> m_function;
};

// ---------------------------------------------------------
// handler class which holds a virtual function and checks for null
// ---------------------------------------------------------
template < class type_1, class type_2, class type_3 >
class t_handler_3
{
public:
	typedef t_handler_base_3<type_1, type_2, type_3> t_function;

	t_handler_3() {}
	t_handler_3( t_function* function ) 
		: m_function( function ) {}

	t_function*       get() const { return m_function; }
	operator t_function* () const { return m_function; }

	void operator()( type_1 arg_1, type_2 arg_2, type_3 arg_3 ) const
	{
		if (m_function != 0)
			(*m_function)( arg_1, arg_2, arg_3 );
	}
protected:
	t_counted_ptr<t_function> m_function;
};



#endif // HANDLER_H_INCLUDED



